Enunciado

Bienvenidos a la Actividad 1, donde pondremos en práctica todo lo aprendido durante el bloque 2. Esta actividad la realizaremos en clase, se terminará en casa (debería completarse en clase) y se entregará el día 8 de octubre.

¿En qué consiste?

Vamos a poner en práctica cuatro aspectos del procesamiento de imágenes:

La finalidad es sencilla. Se os dará una imagen, a color, que tiene varias tonalidades y que está pintada con círculos.

La actividad consiste en contar el número de círculos de la imagen. image.png

Evaluación

Se evaluará de la siguiente manera:

Formato de entrega

No se aceptará el formato .ipynb Habilitaré una actividad en Canvas para que podáis subir ambos archivos.

Inicialización

En primer lugar, cargamos todos los paquetes/frameworks que nos van a hacer falta. Se recomienda visitar la web: https://scikit-image.org/ para ver todas las funcionalidades que permite Scikit Image.

Cargar la imagen

Lo primero de todo, vamos a leer la imagen. Recuerda que hay que subir la imagen cada vez que inicies sesión en el notebook y que la ruta se mira haciendo botón derecho sobre el archivo.

Con lo cual, aquí vamos a hacer dos cosas:

Hacemos esto para luego posteriormente umbralizar la imagen en escala de grises.

Umbralizar la imagen con varios métodos

Vamos a probar ahora diferentes métodos para umbralizar la imagen. Se pide en esta actividad:

  1. Umbralización binaria simple: Convierte los píxeles a blanco si están por encima del umbral y a negro si están por debajo del umbral.

Podemos modificar el umbral. Si aumentas el valor del umbral se volverá más restrictivo y solo los píxeles con valores de intensidad mucho más altos que 100 serán considerados blancos. Esto hara que haya regiones más oscuras. Si disminuyes el valor del umbral se volverá menos restrictivo y más píxeles tendrán intensidad suficiente para ser considerados blancos. Se verán zonas más claras.

Con un valor de umbral tan bajo, los puntos casi no se distinguen en las reguiones más claras de la imagen.

Con un valor de umbral muy alto, en las zonas claras los puntos se distinguen muy bien pero en las zonas ocuras apenas podemos diferenciar puntos.

  1. Umbralización de Otsu: Calcula automáticamente el umbral óptimo para separar los objetos del fondo.
  1. Umbralización de Li: es un método de umbralización automática que se utiliza para binarizar una imagen en función de la distribución de los niveles de gris en la misma. Este método calcula un umbral óptimo de manera automática utilizando la información estadística de la imagen.
  1. Umbralización binaria simple (otro código)
  1. Umbralización de Li con umbral personalizado

Métodos threshold_niblack y threshold_sauvola: son algoritmos utilizados en el procesamiento de imágenes para la umbralización local. Estos métodos no aplican un umbral único a toda la imagen; en cambio, calculan un umbral diferente para cada píxel en función de su entorno local. Esto es útil en situaciones en las que la iluminación de la imagen es inconsistente o variable.

  1. Sauvola: Este método también calcula un umbral local para cada píxel, pero se basa en la media y la desviación estándar locales junto con un término de contraste. Similar al método Niblack, si el valor del píxel es mayor que el umbral, se asigna un valor binario de 1 (blanco); de lo contrario, se asigna un valor de 0 (negro).
  1. Niblack. Este método se basa en un umbral local calculado para cada píxel como una ponderación de la media y la desviación estándar de los valores de los píxeles en su vecindario. Si el valor del píxel es mayor que el umbral, se asigna un valor binario de 1 (blanco); de lo contrario, se asigna un valor de 0 (negro).

Vamos a probar a rotar la imagen

Si se rota una imagen 180 grados antes de umbralizarla, no siempre se obtendrá el mismo resultado. El resultado puede diferir según la imagen y el algoritmo de umbralización utilizado. Esto se debe a cómo funcionan los algoritmos de umbralización y cómo la rotación de la imagen puede afectarlos. Un factor que puede afectar es la orientación de los objetos. Si los obajetos rotan es posible que los algoritmos de umbralización identifiquen de manera diferente las regiones de interés.

La umbralización es un proceso crucial en el procesamiento de imágenes que transforma una imagen en escala de grises en una imagen binaria, con dos grupos de píxeles, uno por encima y otro por debajo del umbral. Para lograr esto, hay una variedad de métodos de umbralización disponibles, cada uno con sus propias características y usos. Aquí hay una comparación general de cinco métodos de umbralización populares: umbralización binaria simple, umbralización de Otsu, umbralización de Li, umbralización de Sauvola y umbralización de Niblack.

Umbralización binaria simple:

Descripción: Este método utiliza un umbral fijo predefinido para separar los píxeles en dos grupos: por encima del umbral y por debajo del umbral. Resultados: Es simple pero no se adapta automáticamente a las variaciones de contraste y luminosidad en la imagen. Funciona bien cuando las condiciones de iluminación son uniformes. Aplicaciones: Útil en situaciones en las que el umbral es conocido y constante. Umbralización de Otsu:

Descripción: Calcula el umbral óptimo de manera automática al minimizar la varianza intraclase, buscando un valor de umbral que maximice la separación entre las clases de píxeles. Resultados: Funciona bien cuando la imagen tiene bimodalidad en su histograma de intensidad. Aplicaciones: Ampliamente utilizado en la segmentación de imágenes médicas y en aplicaciones de reconocimiento de objetos. Umbralización de Li:

Descripción: Calcula el umbral óptimo de manera automática utilizando una combinación de estadísticas locales y globales. Resultados: Funciona bien en imágenes con variaciones locales y contrastes diferentes. Aplicaciones: Útil en imágenes con variaciones de iluminación y sombras. Método Sauvola:

Descripción: Calcula el umbral local en ventanas pequeñas y adapta el umbral en función de la media y la desviación estándar locales. Resultados: Funciona bien en imágenes con variaciones locales de iluminación y contraste. Aplicaciones: Útil en OCR (reconocimiento óptico de caracteres) y procesamiento de documentos. Método Niblack:

Descripción: Similar al método Sauvola, calcula el umbral local en ventanas pequeñas utilizando la media y la desviación estándar locales. Resultados: Funciona bien en imágenes con variaciones locales de iluminación y contraste. Aplicaciones: Utilizado en aplicaciones de segmentación de texto en documentos y OCR.

El tipo de imagen y las circunstancias del problema determinan el método de umbralización. En general, los métodos de umbralización adaptativa, como Sauvola y Niblack, suelen funcionar mejor en imágenes con variaciones locales de iluminación, mientras que métodos como Otsu y Li son útiles cuando se requiere un umbral global ideal. Es crucial probar y ajustar estos métodos en función del tipo de imagen y el objetivo de procesamiento.

Morfología Matemática

Como se puede apreciar en la imagen hay varios elementos imperfectos:

Mediante el uso de morfología matemática (concretamente los cuatro operadores visto en clase) y los posibles elementos estructurales existentes, se pide:

Obtenemos resultados muy parecidos. Disk (Disco): Es una opción adecuada para suavizar y eliminar pequeños detalles en la imagen. Puede ayudar a cerrar pequeños huecos en objetos. Diamond (Diamante): Es útil para afinar y hacer que los objetos sean más puntiagudos. Puede ser eficaz para realzar bordes finos. Ball (Esfera): Funciona bien para suavizar y hacer crecer objetos en todas las direcciones. Útil para rellenar huecos en objetos grandes. Rectangle (Rectángulo): Es versátil y puede adaptarse a diferentes formas de objetos. Útil para cambios direccionales en la morfología.

Contando círculos

Haciendo uso de las funcionalidades cargadas al principio, se pide hacer una función que:

Por último, ¿qué se podría hacer para asegurar que no se tienen en cuenta posibles errores en la umbralización como pequeños puntos o posible ruido que haya llegado hasta este punto?

Primero realizaremos el método niblack y guardamos su imagen resultante para luego poder hacer el conteo de puntos de esa imagen.

Aumentar k aumentará el umbral, requiriendo valores de intensidad más altos para considerar un píxel como objeto, lo que podría reducir la detección de puntos. Disminuir k disminuirá el umbral, permitiendo detectar más puntos. La elección de k depende de la imagen y de lo que quieras detectar.

(Bonus) Automatizamos el proceso de extracción

Esta sección no es obligatoria pero la pongo para aquellos que quieran saber "¿y ahora qué se haría?".

Lo que hemos hecho hasta ahora es:

Es decir, tenemos varios parámetros y tenemos una función que nos dice cuál es el número de puntos dada una imagen. Variando dichos parámetros, variará también el número de puntos, pero no parece haber una relación directa.

También no hay que olvidar que desconocemos el número de puntos (nunca se ha dicho, aunque siempre puedes contarlos), por lo que no podemos seguir un proceso de aprendizaje supervisado (tipo descenso del gradiente sobre los parámetros anteriores para encontrar el mejor resultado).

Pero lo que sí podemos hacer es iterar el valor de los parámetros para alcanzar un máximo de puntos (asumiendo que dicho máximo corresponderá con el mejor resultado). Esto suele hacerse cuando no sabemos exáctamente el resultado que esperamos.

En definitiva, ahora se buscaría realizar un proceso iterativo para encontrar el valor máximo del número de puntos. Para ello haría falta:

Podría decirse que esa combinación de parámetros es la mejor.

Al igual que en el anterior caso anterior, modificando los parametros window_size (siempre un número impar) y el valor de la k, variará el número de puntos de una forma u otra.

window_size (Tamaño de la ventana): Este parámetro determina el tamaño de la ventana utilizada para calcular el umbral local. Un valor mayor de window_size significa que se considera un área más grande alrededor de cada píxel para calcular el umbral local. Si aumentas window_size, es más probable que obtengas umbrales locales más estables y menos propensos al ruido, pero también puedes perder detalles finos. Por otro lado, si disminuyes window_size, los umbrales locales pueden ser más sensibles al ruido y a las pequeñas variaciones en la intensidad de la imagen, lo que podría resultar en más puntos detectados.

k: Este parámetro ajusta la sensibilidad del umbral local. Valores mayores de k aumentan el umbral local, lo que significa que se requerirá una intensidad más alta para considerar un píxel como parte de un objeto. Un valor de k más alto puede reducir la detección de puntos al requerir que los objetos sean más brillantes para ser detectados como puntos. Por otro lado, valores más bajos de k pueden permitir detectar más puntos al ser menos restrictivos en términos de umbral.